package com.gsn.engine.myplay;

import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import aurelienribon.tweenengine.BaseTween;
import aurelienribon.tweenengine.Tween;
import aurelienribon.tweenengine.TweenCallback;
import aurelienribon.tweenengine.TweenManager;

import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.gsn.engine.GsnException;
import com.gsn.engine.gdx.assets.GsnManagerTexture;
import com.gsn.engine.tween.ActorAccessor;
import com.gsn.engine.utility.UtilityGettor;

abstract public class GsnGame implements ApplicationListener {
	public GsnScreen currentScreen;
	public float width, height;
	private BitmapFont font;
	SpriteBatch batch;
	private Timer timer;
	private long oldTime = 0;
	private long nowTime = 0;
	public static boolean transform = true;

	public final List<GsnManagerTexture> assetList = new ArrayList<GsnManagerTexture>();

	public TweenManager tweenManger = new TweenManager();
	public TweenManager glTweenManager = new TweenManager();

	static {
		Tween.registerAccessor(Actor.class, new ActorAccessor());
	}

	public void addScreen(GsnScreen screen) {
		screen.game = this;
	}

	public void remove(final Actor actor, float dur) {
		Tween.call(new TweenCallback() {

			@Override
			public void onEvent(EventType type, BaseTween source) {
				// TODO Auto-generated method stub
				actor.remove();
			}
		}).delay(dur).start(tweenManger);
	}

	public void call(TweenCallback callback, float dur) {
		Tween.call(callback).delay(dur).start(tweenManger);
	}

	public void runInGLThread(TweenCallback callback, float dur) {
		Tween.call(callback).delay(dur).start(glTweenManager);
	}

	@Override
	public void create() {
		width = Gdx.graphics.getWidth();
		height = Gdx.graphics.getHeight();
		font = new BitmapFont();
		font.setColor(0.4f, 0.7f, 0.1f, 1f);
		batch = new SpriteBatch();

		timer = new Timer();
		final int fps = 30;
		final int kc = 1000 / fps;
		oldTime = System.currentTimeMillis();
		timer.schedule(new TimerTask() {

			@Override
			public void run() {
				nowTime = System.currentTimeMillis();
				if (tweenManger != null) {
					try {
						tweenManger.update((int) (nowTime - oldTime));
					} catch (Exception e) {
						// TODO: handle exception
						tweenManger.killAll();

						e.printStackTrace();
					}
				}
				oldTime = nowTime;

			}
		}, kc, kc);
	}

	@Override
	public void render() {
		// GsnTween.manager.update(Gdx.graphics.getDeltaTime());
		glTweenManager.update((int) (Gdx.graphics.getDeltaTime() * 1000));
		Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);

		for (GsnManagerTexture tmp : assetList)
			if (tmp.loaded)
				if (tmp.update())
					try {
						tmp.assignContent();
					} catch (GsnException e) {
						e.printStackTrace();
					}

		if (currentScreen != null) {
			currentScreen.act(Gdx.graphics.getDeltaTime());
			try {
				currentScreen.draw();
			} catch (Exception ex) {
				ex.printStackTrace();
				for (GsnLayer layer : currentScreen.layers) {
					try {
						layer.endSpriteBatch();
					} catch (Exception e) {
						// TODO: handle exception
						e.printStackTrace();
					}

				}
			}

			batch.begin();
		//	font.draw(batch, "FPS : " + Gdx.graphics.getFramesPerSecond(), 10, font.getLineHeight());
			batch.end();
		}

	}

	public void setScreen(GsnScreen screen) {
		if (currentScreen != null)
			currentScreen.onHideScreen();
		currentScreen = screen;
		currentScreen.onShowScreen();

	};

	@Override
	public void dispose() {
		// TODO Auto-generated method stub
		timer.cancel();
	}

	@Override
	public void resume() {
		if (currentScreen != null) {
			// UtilityGettor.inst().showProgressDialog("Loading", "Loading...");
			for (GsnManagerTexture tmp : currentScreen.assetNeedList) {
				tmp.finishLoading();
			}
			// UtilityGettor.inst().hideProgressDialog();
		}

	}

	public abstract void quitGame();

}
